#!/usr/bin/perl -w
use strict;

# example files: IMT_abstract_tag
my $prediction_file = $ARGV[0];
my $dict_file = "BC3_data/BC3_IMT_Training/annotations/allowed_PSI-MI_ids_and_synonyms.txt";

my %id_concept;
my %id_terms;
my %term_inserted;
&read_dictionary;

my %sent_term;
my %sent_id;
my %sent_context;
my $prev_pmid = "";
open (FD, $prediction_file)
	|| die ("Unable to open: $prediction_file\n");
while (<FD>){ 
	chop;
	
	# 0: PMID
	# 1: SentNo
	# 2 Context
	# 3: Term
	# 4: ID
	# 5: Type
	# 6: No of occurrences
	# 7: Start
	# 8: End
	# 9: Occurrence Position
	# 10: Length
	# 11: Confidence
	# 19008224	1	..air cells, was found by yeast two\-hybrid protocols to bind the cytoplas..	two\-hybrid	MI:0018	Concept	1	105	175	135	11	1
	my @tfs = split (/\t/, $_);
	if ($prev_pmid ne "" and $prev_pmid ne $tfs[0]){ 
		# remove duplicates
		&remove_duplicates;
		undef %sent_term;	
		undef %sent_id;
		undef %sent_context;
	}	

	$prev_pmid = $tfs[0];
	
	if (not exists($sent_id{$tfs[1]})){
		$sent_id{$tfs[1]} = $tfs[9] . "#" . $tfs[4];
		$sent_term{$tfs[1]} = $tfs[3];
		$sent_context{$tfs[1]} = $_;
	} else { 
		$sent_id{$tfs[1]} .= "|" . $tfs[9] . "#" . $tfs[4];
		$sent_term{$tfs[1]} .= "#" . $tfs[3];
		$sent_context{$tfs[1]} .= "|" . $_;
	}
	# print "Storing $_\n";
}
close (FD);

sub remove_duplicates{
	foreach my $sent_key (keys(%sent_id)){
		# print $sent_key . "\n";
		if (not exists($sent_id{$sent_key})){
			print  $sent_key . " " .$prev_pmid . "\n"; 
			print "EXITING\n";
			exit;
		}
		my @occus = split (/\|/, $sent_id{$sent_key});
			
		if (scalar(@occus) == 1){ 
			# print "FINAL\t" . $sent_context{$sent_key} . "\n";
			print $sent_context{$sent_key} . "\n";
			next;
		} 
		
		my @terms = split (/\#/, $sent_term{$sent_key});
		if (not exists($sent_context{$sent_key})){
			print $sent_key . " " . $prev_pmid . "\n"; 
			print "EXITING\n";
			exit;
		}
		my @contexts = split (/\|/, $sent_context{$sent_key});
		my %remove_flag;
		for (my $i = 0; $i < scalar(@occus); $i++){ 
			next if (exists($remove_flag{$i}));
			my ($pos_i, $id_i) = split (/\#/, $occus[$i]);
			my $end_i = $pos_i + length($terms[$i]);  	
			for (my $j = $i + 1; $j < scalar(@occus); $j++){ 
				my ($pos_j, $id_j) = split (/\#/, $occus[$j]);
				my $end_j = $pos_j + length($terms[$j]); 
				
				if (length($terms[$i]) > length($terms[$j])){ 
					if ($pos_j >= $pos_i and $end_j <= $end_i){ 
						# print "Removing $terms[$j] for $terms[$i] in $prev_pmid [1]\n";
						$remove_flag{$j} = 1;
					} 
				}elsif (length($terms[$i]) < length($terms[$j])){ 
					if ($pos_i >= $pos_j and $end_i <= $end_j){ 
						# print "Removing $terms[$i] for $terms[$j] in $prev_pmid [2]\n";
						$remove_flag{$i} = 1;
					}
				} elsif (length($terms[$i]) == length($terms[$j])){ 
					if ($pos_i == $pos_j and $end_i == $end_j){ 
						# print "Removing $terms[$i] for $terms[$j] in $prev_pmid [3]\n";
						$remove_flag{$j} = 1;
					}
				}	
			}
			
			if (not exists($remove_flag{$i})){ 
				# print "FINAL\t" . $contexts[$i] . "\n";
				print $contexts[$i] . "\n";
			}
		}
	}		
}

sub read_dictionary{ 
	;
	open (FD, $dict_file) ||
		die ("Unable to open: $dict_file\n");
	while (<FD>){ 
		chop;
		#MI:0004	affinity chromatography technology	Concept
		my @tfs = split (/\t/, $_);

		if ($tfs[1] =~ /^[A-Z]+$/){ 
			my $term = $tfs[1];
			update_term_arrays ($term, $tfs[2], $tfs[0]);	
			update_term_arrays (lc($term), $tfs[2], $tfs[0]);	
			next;
		} 

		if (not $tfs[1] =~ /\W/){ 
			# print "HERE\n";
			my $term = $tfs[1];
			update_term_arrays ($term, $tfs[2], $tfs[0]);	
		
			#First letter CAPITALIZED	
			$term = $tfs[1];
			if (not $term =~ /^[A-Z]/){ 
				$term = get_capitalized($tfs[1]);
				update_term_arrays (lc($term), $tfs[2], $tfs[0]);	
			}

			# Upper case for lower case
			$term = $tfs[1];
			if ($term =~ /^[a-z0-9]+$/){ 
				update_term_arrays (uc($term), $tfs[2], $tfs[0]);	
			}
			
			# Lower case for upper case
			$term = $tfs[1];
			if ($term =~ /^[A-Z0-9]+$/){ 
				update_term_arrays (lc($term), $tfs[2], $tfs[0]);	
			}
			next;
		}

		# Term AS IT IS
		my $term = $tfs[1];
		$term =~ s/([^a-zA-Z0-9])/\\$1/g;	
		update_term_arrays ($term, $tfs[2], $tfs[0]);	
		
		# Changing - to space and space to -
		$term = $tfs[1];
		if ($term =~ /\-/){ 
			$term =~ s/\-/\ /g;
		} elsif ($term =~ /\ /){ 
			$term =~ s/\ /\-/g;
		}
		$term =~ s/([^a-zA-Z0-9])/\\$1/g;	
		update_term_arrays ($term, $tfs[2], $tfs[0]);	
		
		# removing all non-alphanumeric character
		$term =~ s/([^a-zA-Z0-9])//g;	
		update_term_arrays ($term, $tfs[2], $tfs[0]);	
		
		# First word CAPITALIZED
		$term = $tfs[1];
		$term = get_capitalized ($tfs[1]); 
		$term =~ s/([^a-zA-Z0-9])/\\$1/g;	
		update_term_arrays ($term, $tfs[2], $tfs[0]);	
		
		$term = $tfs[1];
		if ($term =~ /\-/){ 
			$term =~ s/\-/\ /g;
		} elsif ($term =~ /\ /){ 
			$term =~ s/\ /\-/g;
		}
		$term =~ s/([^a-zA-Z0-9])/\\$1/g;	
		update_term_arrays (get_capitalized($term), $tfs[2], $tfs[0]);
			
		# Each word CAPITALIZED
		$term = get_term_capitalized($tfs[1]);
		$term =~ s/([^a-zA-Z0-9])/\\$1/g;	
		update_term_arrays ($term, $tfs[2], $tfs[0]);	
		
		if ($term =~ /\-/){ 
			$term =~ s/\-/\ /g;
		} elsif ($term =~ /\ /){ 
			$term =~ s/\ /\-/g;
		}
		update_term_arrays ($term, $tfs[2], $tfs[0]);	
	}
	close (FD);
}

sub get_term_capitalized{ 
		my ($word) = @_;
	
		my @tokens = split (/[\ \-]/, $word);
		my $separator = " ";
		if ($word =~ /\-/){ 
			$separator = "-";
		}
		my $term = "";
		for (my $i = 0; $i < scalar(@tokens); $i++){ 
			$term .= get_capitalized($tokens[$i]) . $separator;
		}
		$term =~ s/\-$//;
		$term =~ s/\ $//;
		return $term;
}

sub get_capitalized{
		my ($word) = @_;
		return (uc(substr($word, 0, 1)) . 
			substr($word, 1, length($word)-1));
}

sub update_term_arrays{ 
	my ($term, $concept, $id) = @_;	
	
	return if (exists($term_inserted{$term}));
	$term_inserted{$term} = 1;
	$id_concept{$id} = $concept;
	if (not exists($id_terms{$id})){ 
		$id_terms{$id} = $term; 
	} else { 
		return if ($id_terms{$id} =~ /$term/);  
		$id_terms{$id} .= "#" . $term; 
	}
}

